package com.sftz.framework.mvc.actionfilter;

import java.util.Enumeration;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.ActionContext;
import org.nutz.mvc.ActionFilter;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.View;

import com.google.common.collect.Maps;
import com.uxuexi.core.common.util.Util;

/**
 * 创建新session的过滤器
 * <p>
 * 解决安全性:会话标识未更新的问题(登录前后) 
 * 将用户进入登陆页面时所产生的会话也就是session清空，然后让跟踪这个会话的cookie过期，这样服务器就不再掌握有关这个会话的任何信息了。
 * 要想与服务器继续通信，就要产生一个新的会话才行。于是会话标示就更新了
 * 
 * @author 朱晓川
 */
public class NewSessionFilter implements ActionFilter {

	private static final Log log = Logs.get();

	@Override
	public View match(ActionContext ac) {

		HttpServletRequest request = Mvcs.getReq();
		HttpSession old = request.getSession();
		log.debug("旧会话标志:" + old.getId());

		//清空数据之前,先将旧session中的数据取出来，以备复制到新session中
		Map<String, Object> data = Maps.newHashMap();
		Enumeration<String> keys = old.getAttributeNames();
		while (!Util.isEmpty(keys) && keys.hasMoreElements()) {
			String key = keys.nextElement();
			data.put(key, old.getAttribute(key));
		}

		try {
			//清空session，此时会话标志jsessionid不会发生改变
			old.invalidate();
			if (request.getCookies() != null) {
				// 获取cookie  
				Cookie cookie = request.getCookies()[0];
				// 让cookie过期  
				cookie.setMaxAge(0);
			}
			//使用新的session
			HttpSession newSession = request.getSession(true);
			//执行数据copy，避免影响session有关业务
			if (!Util.isEmpty(data)) {
				Set<String> keySet = data.keySet();
				for (String k : keySet) {
					newSession.setAttribute(k, data.get(k));
				}
				data = null;
			}
			log.debug("新会话标志:" + newSession.getId());
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
}
